Denoising by Sobolev and Total Variation Flows
It is possible to denoise an image using either a variation flow of some regularization prior. This leads to a linear or non-linear PDE. We consider here the linear Sobolev and non-linear TV flow, that corresponds to the heat and mean-curvature differential equations.
Contents
Installing toolboxes and setting up the path.
You need to download the following files: signal toolbox and general toolbox.
You need to unzip these toolboxes in your working directory, so that you have toolbox_signal and toolbox_general in your directory.
For Scilab user: you must replace the Matlab comment '%' by its Scilab counterpart '//'.
Recommandation: You should create a text file named for instance numericaltour.sce (in Scilab) or numericaltour.m (in Matlab) to write all the Scilab/Matlab command you want to execute. Then, simply run exec('numericaltour.sce'); (in Scilab) or numericaltour; (in Matlab) to run the commands.
Execute this line only if you are using Matlab.
getd = @(p)path(p,path); % scilab users must *not* execute this
Then you can add the toolboxes to the path.
getd('toolbox_signal/'); getd('toolbox_general/');
Prior and Gradient Flows
For a given image
R
A PDE flow performs a continuous gradient descent of the energy. It defines a continuous series of images
t
ft=−GradJ(ft)where 
J(f)
In a discrete setting, this continuous flow is discretized using an explicit Euler scheme in time, which corresponds to a
gradient descent algorithm to minimize the energy
It defines a series of images
).png)
N
+1)=f(
)+
GradJ(f(
))
One can sees that
)
ft.png)


.png)
Note that for
)
+


2maxf
D2J(f)

Sobolev Prior
The Sobolev image prior is a quadratic prior, i.e. an Hilbert (pseudo)-norm.
First we load a clean image.
n = 256;
name = 'hibiscus';
f0 = load_image(name,n);
f0 = rescale( sum(f0,3) );
For a smooth continuous function


f(x)
2dx Where the gradient vector at point
f(x)=
x1
f(x)
x2
f(x)
For a discrete pixelized image
RN
n
f(x)
R2
Gr = grad(f0);
One can compute the norm of gradient, 
f(x)
d = sqrt(sum3(Gr.^2,3));
Display.
clf; imageplot(Gr, strcat(['grad']), 1,2,1); imageplot(d, strcat(['|grad|']), 1,2,2);
The Sobolev norm is the (squared)
f
RN
2
sob = sum(d(:).^2);
Heat Diffusion for Denoising
The gradient descent of the Sobolev norm corresponds to the heat diffusion. It can be used to perform denoising.
Add some noise to the original image.
sigma = .14; y = f0 + randn(n,n)*sigma;
The gradient of the Sobolev norm is (minus) the Laplacian.
f=−div(
f)The Heat diffusion PDE thus reads:
t
ft=
ftInitialize the PDE at time
fHeat = y;
The Laplacian is computed using a finite differences divergence
L = div(grad(fHeat));
Display.
clf; imageplot(fHeat, 'Image', 1,2,1); imageplot(L, 'Laplacian', 1,2,2);
For the discretized PDE in time to minimize

2

=41To have a good precision, we use an even smaller step size:
tau = .05;
Stopping time for the PDE resolution.
T = 3;
Number of iterations to reach T.
niter = ceil(T/tau);
Gradient of the Sobolev norm is minus the Laplacian
G = -div(grad(fHeat));
Descent.
fHeat = fHeat - tau*G;
Exercice 1: (the solution is exo1.m) Compute niter iterations of the Heat diffusion. Keep track of err(i)=snr(f0,fHeat). Keep track of the optimal denoising result fHeat0.
exo1;
Plot the evolution of snr(f0,fHeat) during the diffusion.
clf; plot( linspace(0,T,niter), err ); axis tight; set_label('t', 'SNR');
Display best "oracle" denoising result.
eheat = max(err); enoisy = snr(f0,y); clf; imageplot(clamp(y), strcat(['Noisy ' num2str(enoisy) 'dB']), 1,2,1); imageplot(clamp(fHeat0), strcat(['Heat diffusion ' num2str(eheat) 'dB']), 1,2,2);
Total Variation Prior
The total variation is a Banach norm. On the contrary to the Sobolev norm, it is able to take into account step edges.
The total variation of a smooth image


f(x)
2dx It is extended to non-smooth images having step discontinuities.
The total variation of an image is also equal to the total length of its level sets.
−
+
L(St(f))dt Where
x
f(x)=t
Exercice 2: (the solution is exo2.m) Compute the total variation of f0.
exo2;
The Gradient of the TV norm is

f
f

The gradient of the TV norm is not defined if at a pixel
f(x)=0
To define a gradient flow, we consider instead a smooth TV norm
(f)=

2+
f(x)
2dx This corresponds to replacing
u

2+
u
2
We display (in 1D) the smoothing of the absolute value.
u = linspace(-5,5)'; clf; subplot(2,1,1); hold('on'); plot(u, abs(u), 'b'); plot(u, sqrt(.5^2+u.^2), 'r'); title('\epsilon=1/2'); axis('square'); subplot(2,1,2); hold('on'); plot(u, abs(u), 'b'); plot(u, sqrt(1^2+u.^2), 'r'); title('\epsilon=1'); axis('square');
The Gradient of the smoothed TV norm is

f
2+
f
2.png)
When .png)

.png)
epsilon_list = [1e-9 1e-2 1e-1 .5]; clf; for i=1:length(epsilon_list) G = div( Gr ./ repmat( sqrt( epsilon_list(i)^2 + d.^2 ) , [1 1 2]) ); imageplot(G, strcat(['epsilon=' num2str(epsilon_list(i))]), 2,2,i); end
Total Variation Diffusion for Denoising
The gradient descent of the TV norm corresponds to a non-linear, edge-preservig diffusion. It can be used to perform denoising.
We set a small enough regularization parameter.
epsilon = 1e-2;
Maximal smoothing time. Not that it is different from the parameter of the heat diffusion because the scalings are different.
T = 1/4;
The step size for diffusion should satisfy:

2.png)


=
4tau = epsilon/4;
Number of iterations to reach T.
niter = ceil(T/tau);
Initial solution for time t=0.
fTV = y;
Compute the gradient of the smoothed TV norm.
Gr = grad(fTV); d = sqrt(sum3(Gr.^2,3)); G = -div( Gr ./ repmat( sqrt( epsilon^2 + d.^2 ) , [1 1 2]) );
One step of descent.
fTV = fTV - tau*G;
Exercice 3: (the solution is exo3.m) Compute niter iterations of the smoothed TV diffusion. Keep track of err(i)=snr(f0,fTV). Keep track of the optimal denoising result fTV0.
exo3;
Plot the evolution of snr(f0,fTV) during the diffusion. Display the error err.
clf; plot( linspace(0,T,niter), err ); axis tight; set_label('t', 'SNR');
Display best "oracle" denoising result.
etv = max(err); enoisy = snr(f0,fTV0); clf; imageplot(clamp(y), strcat(['Noisy ' num2str(enoisy) 'dB']), 1,2,1); imageplot(clamp(fTV0), strcat(['TV diffusion ' num2str(etv) 'dB']), 1,2,2);